/* global window */
import cloneDeep from 'lodash.clonedeep'
import moment from 'moment'

export classnames from 'classnames'
export config from './config'
export request from './request'
export {color} from './theme'

// 连字符转驼峰
String.prototype.hyphenToHump = function () {
  return this.replace(/-(\w)/g, (...args) => {
    return args[1].toUpperCase()
  })
}

// 驼峰转连字符
String.prototype.humpToHyphen = function () {
  return this.replace(/([A-Z])/g, '-$1').toLowerCase()
}

export function getTimeDistance (type) {
  const now = new Date()
  const oneDay = 1000 * 60 * 60 * 24

  if (type === 'today') {
    now.setHours(0)
    now.setMinutes(0)
    now.setSeconds(0)
    return [moment(now), moment(now.getTime() + (oneDay - 1000))]
  }

  if (type === 'week') {
    let day = now.getDay()
    now.setHours(0)
    now.setMinutes(0)
    now.setSeconds(0)

    if (day === 0) {
      day = 6
    } else {
      day -= 1
    }

    const beginTime = now.getTime() - day * oneDay

    return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))]
  }

  if (type === 'month') {
    const year = now.getFullYear()
    const month = now.getMonth()
    const nextDate = moment(now).add(1, 'months')
    const nextYear = nextDate.year()
    const nextMonth = nextDate.month()

    return [
      moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`),
      moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000),
    ]
  }

  if (type === 'year') {
    const year = now.getFullYear()

    return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)]
  }
}

export function fixedZero (val) {
  return val * 1 < 10 ? `0${val}` : val
}

// 日期格式化
Date.prototype.format = function (format) {
  const o = {
    'M+': this.getMonth() + 1,
    'd+': this.getDate(),
    'h+': this.getHours(),
    'H+': this.getHours(),
    'm+': this.getMinutes(),
    's+': this.getSeconds(),
    'q+': Math.floor((this.getMonth() + 3) / 3),
    S: this.getMilliseconds(),
  }
  if (/(y+)/.test(format)) {
    format = format.replace(RegExp.$1, `${this.getFullYear()}`.substr(4 - RegExp.$1.length))
  }
  for (let k in o) {
    if (new RegExp(`(${k})`).test(format)) {
      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : (`00${o[k]}`).substr(`${o[k]}`.length))
    }
  }
  return format
}

/**
 * 转换消息类型
 * @param type
 */
export function toMessageType (type) {
  switch (type) {
    case 1:
      return "文本"
    case 3:
      return "图片"
    case 34:
      return "语音"
    case 42:
      return "名片"
    case 47:
      return "表情"
    case 48:
      return "位置"
    case 49:
      return "文件/分享"
    case 50:
      return "视频/语音通话"
    case 10000:
      return "通知消息"
    case 1048625:
      return "动画表情"
    case 285212721:
      return "公众号消息"
    case 318767153:
      return "提示消息"
    case 419430449:
      return "转账"
    case 436207665:
      return "红包"
    case 570425393:
      return "群成员操作"
    default:
      return "未知类型"
  }
}

/**
 * 转换消息
 * @param type
 * @param val
 */
export function transferMsg (val, type) {
  switch (type) {
    case 3:
      return "[图片]"
    case 34:
      return "[语音]"
    case 42:
      return "[名片]"
    case 47:
      return "[表情包]"
    case 48:
      return "[位置分享]"
    case 49:
      return "[文件/分享]"
    case 50:
      return "[视频/语音通话]"
    case 1048625:
      return "[动画表情]"
    case 285212721:
      return "[公众号消息]"
    case 419430449:
      return "[收到转账]"
    case 436207665:
      return "[收到红包]"
    case 570425393:
      return "[群成员操作]"
    default:
      return val
  }
}

/**
 * @param  name {String}
 * @return  {String}
 */
export function queryURL (name) {
  let reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i')
  let r = window.location.search.substr(1).match(reg)
  if (r != null) return decodeURI(r[2])
  return null
}

/**
 * 数组内查询
 * @param   {array}      array
 * @param   {String}    id
 * @param   {String}    keyAlias
 * @return  {Array}
 */
export function queryArray (array, key, keyAlias = 'key') {
  if (!key) {
    return null
  }

  if (!(array instanceof Array)) {
    return null
  }
  const item = array.filter(_ => _[keyAlias] === key)
  if (item.length) {
    return item[0]
  }
  return null
}

/**
 * 转换成图片表情
 */
export function toEmotion (text, isNoGif) {
  const list = ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴', '睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶', '难过', '酷', '冷汗', '抓狂', '吐', '偷笑', '愉快', '白眼', '傲慢', '饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗', '咒骂', '疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见', '擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼', '哈欠', '鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀', '西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头', '玫瑰', '凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀', '足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱', '强', '弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你', 'NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火', '转圈', '磕头', '回头', '跳绳', '挥手', '激动', '街舞', '献吻', '左太极', '右太极', '嘿哈', '捂脸', '奸笑', '机智', '皱眉', '耶', '红包', '鸡']

  if (!text) {
    return text
  }

  text = text.replace(/\[[\u4E00-\u9FA5]{1,3}\]/gi, function (word) {
    const newWord = word.replace(/\[|\]/gi, '')
    const index = list.indexOf(newWord)
    const backgroundPositionX = -index * 24
    let imgHTML = ''
    if (index < 0) {
      return word
    }

    if (isNoGif) {
      if (index > 104) {
        return word
      }
      imgHTML = `<i class="static-emotion" style="background:url(https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/default218877.gif) ${backgroundPositionX}px 0"></i>`
    } else {
      const path = index > 104 ? '/img' : 'https://res.wx.qq.com/mpres/htmledition/images/icon'
      imgHTML = `<img class="static-emotion-gif" style="vertical-align: middle" src="${path}/emotion/${index}.gif">`
    }
    return imgHTML
  })
  return text
}

/**
 * 查询 ele 元素是否在 array 中存在
 * @param array
 * @param ele
 * @return 若存在则返回 ele 在数组中的索引，否则返回 -1
 */
export function inArray (array, ele) {
  for (let i = 0; i < array.length; i++) {
    let _this = array[i]
    if (ele === _this) {
      return i
    }
  }
  return -1
}

/**
 * 数组格式转树状结构
 * @param   {array}     array
 * @param   {String}    id
 * @param   {String}    pid
 * @param   {String}    children
 * @return  {Array}
 */
export function arrayToTree (array, id = 'id', pid = 'pid', children = 'children') {
  let data = cloneDeep(array)
  let result = []
  let hash = {}
  data.forEach((item, index) => {
    hash[data[index][id]] = data[index]
  })

  data.forEach((item) => {
    let hashVP = hash[item[pid]]
    if (hashVP) {
      !hashVP[children] && (hashVP[children] = [])
      hashVP[children].push(item)
    } else {
      result.push(item)
    }
  })
  return result
}

export function treeToArray (tree, result, children = 'children') {
  tree.map(_ => {
    result.push(_)
    if (_[children]) {
      treeToArray(_[children], result, children)
    }
  })
}
